/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package matematicadiscretaxml;

import arbol_prueba.BTree;
import java.util.ArrayList;

/**
 *
 * @author diego
 */
public class Seleccion {
 
    private ArrayList lista_lexemas = new ArrayList();

    ObjetoQuery tabla_obj_query[][] = new ObjetoQuery[0][0];//TABLA QUE RESULTA DEL PRODUCTO CARTESIANO
    ObjetoQuery vector_select[] = new ObjetoQuery[0];//VECTOR DE CAMPOS DEL SELECT
    ArrayList lista_errores_seleccion = new ArrayList();//GUARDA LOS ERRORES

    public Seleccion(){}

    public Seleccion(ArrayList _lista_lexemas)
    {
        lista_lexemas = _lista_lexemas;
    }

    public void generarArbolSintacticoSeleccion()
    {
        Select obj_select = new Select(lista_lexemas);
        From obj_from = new From(lista_lexemas);
        Where obj_where = new Where(lista_lexemas);
        BTree sub_arbol_select = null;
        BTree sub_arbol_from = null;
        BTree sub_arbol_where = null;

        System.out.println("**************************************************************");
        obj_select.ingresarPilas();
        sub_arbol_select = obj_select.generarSubArbolSelect(new BTree("nulo"));
        lista_errores_seleccion.addAll(obj_select.getLista_errores_select());
        if(lista_errores_seleccion.isEmpty())
        {
            sub_arbol_select.imprimePostOrden();
            System.out.println("**************************************************************");
            obj_from.ingresarPilas();
            sub_arbol_from = obj_from.generarSubArbolFrom(new BTree("nulo"));
            lista_errores_seleccion.addAll(obj_from.getLista_errores_from());
            if(lista_errores_seleccion.isEmpty())
            {
                sub_arbol_from.imprimePostOrden();
                System.out.println("**************************************************************");
                obj_where.ingresarPilas();
                if(!obj_where.pila_pal_reserv.empty())
                {
                    sub_arbol_where = obj_where.generarSubArbolWhere(new BTree("nulo"));
                    lista_errores_seleccion.addAll(obj_where.getLista_errores_where());
                    if(lista_errores_seleccion.isEmpty())
                    {
                        sub_arbol_where.imprimePostOrden();
                        if(lista_errores_seleccion.isEmpty())
                        {
                            ejecutarSeleccion(sub_arbol_select,sub_arbol_from,sub_arbol_where);
                        }
                    }
                }
                else
                {
                    ejecutarSeleccion(sub_arbol_select,sub_arbol_from, null);
                }
            }
        }
    }

    public void ejecutarSeleccion(BTree sub_arbol_select, BTree sub_arbol_from, BTree sub_arbol_where)
    {
        recorrerSubArbolFrom(sub_arbol_from);
        if(lista_errores_seleccion.isEmpty())
        {
            if(sub_arbol_where != null)
            {
                recorrerSubArbolWhere(sub_arbol_where, sub_arbol_from);
            }
            if(lista_errores_seleccion.isEmpty())
            {
                recorrerSubArbolSelect(sub_arbol_select, sub_arbol_from);
                if(!lista_errores_seleccion.isEmpty())
                {
                    tabla_obj_query = new ObjetoQuery[0][0];
                }
                else
                {
                    imprimirMatriz(tabla_obj_query);
                }
            }
            else
            {
                tabla_obj_query = new ObjetoQuery[0][0];
            }
        }
        else
        {
            tabla_obj_query = new ObjetoQuery[0][0];
        }
    }


    public void recorrerSubArbolSelect(BTree nodo, BTree nodo_from )
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolSelect(nodo.getIzquierda(), nodo_from);
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolSelect(nodo.getDerecha(), nodo_from);
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4 )
        {
            int num_repitencias = 0;
            switch(buscarPuntoCadena(((Lexema)nodo.getElement()).getLexema()))
            {
                case 0:
                    num_repitencias = buscarCamposEnArbolFrom(nodo_from, ((Lexema)nodo.getElement()).getLexema());

                    if(num_repitencias  == 1)
                    {
                        String tabla_campo = ((Lexema)nodo.getElement()).getLexema();
                        String nombre_tabla = buscarTablaDeCampo(nodo_from, tabla_campo);

                        if( !nombre_tabla.equals("") )
                        {
                            generarTablaSelect(new ObjetoQuery(nombre_tabla, tabla_campo, null));
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS SELECT", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                        }
                    }
                    else
                    {
                        if( ((Lexema)nodo.getElement()).getLexema().equals("*") )
                        {
                            /*
                             * ACA SE DEBEN MOSTRAR TODAS LSO CAMPOS DE FROM
                             */
//                            JOptionPane.showMessageDialog(null, "NO ESTA IMPLEMENTADO");
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS SELECT", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                        }
                    }
                    break;
                case 1:
                    String tabla_campo = ((Lexema)nodo.getElement()).getLexema();
//                    System.out.println("PARTE TABLA"+tabla_campo.substring(0, tabla_campo.indexOf('.')));
//                    System.out.println("PARTE CAMPO"+tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() ));
                    num_repitencias = buscarCamposEnArbolFrom(nodo_from, tabla_campo.substring(tabla_campo.indexOf('.')+1,tabla_campo.length())
                                                                            , tabla_campo.substring(0, tabla_campo.indexOf('.')));
                    if(num_repitencias == 1)
                    {
                        String nombre_tabla = tabla_campo.substring(0, tabla_campo.indexOf('.'));
                        if( !nombre_tabla.equals("") )
                        {
                            generarTablaSelect(new ObjetoQuery(nombre_tabla, tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() ), null));
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS SELECT", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                        }
                    }
                    else
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS SELECT", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                    }
                    break;
                default:
                    lista_errores_seleccion.add(new Error("CAMPOS SELECT", "UN IDENTIFICADOR EN WHERE DEBE TENER A LO MAS UN PUNTO"));
                    break;
            }
        }
        else if(((Lexema)nodo.getElement()).getTipo_lexema() == 2)
        {
            /*
             * ACA NO SE HACE NADA PS ES UN SIMBOLO : , 
             */
        }
        else if(((Lexema)nodo.getElement()).getTipo_lexema() == 5)
        {
            generarTablaSelect(new ObjetoQuery("%constante_cadena", ((Lexema)nodo.getElement()).getLexema(), ((Lexema)nodo.getElement()).getLexema()));
        }
        else if(((Lexema)nodo.getElement()).getTipo_lexema() == 6)
        {
            generarTablaSelect(new ObjetoQuery("%constante_numero", ((Lexema)nodo.getElement()).getLexema(), ((Lexema)nodo.getElement()).getLexema()));
        }
        else if(((Lexema)nodo.getElement()).getTipo_lexema() == 3)
        {
            /*
             * ERROR
             */
        }

        else if( ((Lexema)nodo.getElement()).getTipo_lexema() == 1
                &&  ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("select") )
        {
            if(tabla_obj_query.length != 0)
            {
                if( !((Lexema)nodo.getIzquierda().getElement()).getLexema().equals("*") )
                {
                    ObjetoQuery tabla_select_aux[][] = new ObjetoQuery[tabla_obj_query.length][vector_select.length];
                    int indice_col_encontrado = -1;

                    imprimirMatriz(tabla_obj_query);

                    for(int i = 0; i<vector_select.length; i++)
                    {
                        if(vector_select[i].getTabla().toLowerCase().equals("alumno_nota"))
                        {
                            System.out.println(i);

                        }
                        for(int j = 0; j<tabla_obj_query[0].length; j++)
                        {
                            if(   vector_select[i].getTabla().toLowerCase().equals(tabla_obj_query[0][j].getTabla().toLowerCase())
                               && vector_select[i].getColumna().toLowerCase().equals(tabla_obj_query[0][j].getColumna().toLowerCase()) )
                            {
                                indice_col_encontrado = j;
                            }
                        }

                        if(indice_col_encontrado == -1)
                        {
                            for(int m = 0; m<tabla_select_aux.length; m++)
                            {
                                tabla_select_aux[m][i] = vector_select[i];
                            }
                        }
                        else
                        {
                            for(int m = 0; m<tabla_select_aux.length; m++)
                            {
                                tabla_select_aux[m][i] = tabla_obj_query[m][indice_col_encontrado];
                            }
                            indice_col_encontrado = -1;
                        }
                    }
                    tabla_obj_query = new ObjetoQuery[tabla_select_aux.length][tabla_select_aux[0].length];
                    tabla_obj_query = tabla_select_aux;
                }
            }
            
        }
        else
        {
            /*
             * ERROR
             */
        }
    }

    public void imprimirMatriz(ObjetoQuery[][] matriz)
    {
        System.out.println("*********** SELECCION **************");
        for(int i = 0; i<matriz.length; i++)
        {
            for(int j = 0; j<matriz[0].length; j++)
            {
                System.out.print(matriz[i][j].getObjeto()+" | ");
//                System.out.print(matriz[i][j].getTabla()+"."+matriz[i][j].getColumna()+" | ");
            }
            System.out.println("");
        }
    }

    public void generarTablaSelect(ObjetoQuery obj_query)
    {
        ObjetoQuery vector_aux[] = new ObjetoQuery[0];

        if(vector_select.length == 0)
        {
            vector_select = new ObjetoQuery[1];
            vector_select[0] = obj_query;
        }
        else
        {
            vector_aux = new ObjetoQuery[vector_select.length+1];

            for(int i = 0; i<vector_select.length; i++)
            {
                vector_aux[i] = vector_select[i];
            }
            vector_aux[vector_select.length] = obj_query;
            vector_select = new ObjetoQuery[vector_aux.length];
            vector_select = vector_aux;
        }
    }

    public void recorrerSubArbolWhere(BTree nodo, BTree nodo_from )
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolWhere(nodo.getIzquierda(), nodo_from);
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolWhere(nodo.getDerecha(), nodo_from);
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4 )
        {
            int num_repitencias = 0;
            switch(buscarPuntoCadena(((Lexema)nodo.getElement()).getLexema()))
            {
                
                case 0:
                    num_repitencias = buscarCamposEnArbolFrom(nodo_from, ((Lexema)nodo.getElement()).getLexema());

                    if(num_repitencias > 1 )
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM"));
                    }
                    else if(num_repitencias == 0)
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                    }
                    break;

                case 1:
                    String tabla_campo = ((Lexema)nodo.getElement()).getLexema();
//                    System.out.println("PARTE TABLA"+tabla_campo.substring(0, tabla_campo.indexOf('.')));
//                    System.out.println("PARTE CAMPO"+tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() ));
                    num_repitencias = buscarCamposEnArbolFrom(nodo_from, tabla_campo.substring(tabla_campo.indexOf('.')+1,tabla_campo.length())
                                                                            , tabla_campo.substring(0, tabla_campo.indexOf('.')));

                    if(num_repitencias == 0)
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                    }
                    break;

                default:
                    lista_errores_seleccion.add(new Error("CAMPOS WHERE", "UN IDENTIFICADOR EN WHERE DEBE TENER A LO MAS UN PUNTO"));
                    break;
            }
        }
        else if(((Lexema)nodo.getElement()).getTipo_lexema() == 5)
        {
            /*
             * ACA NO SE HACE NADA PS ES CONSTANTE CADENA
             */
        }
        else if(((Lexema)nodo.getElement()).getTipo_lexema() == 6)
        {
            /*
             * ACA NO SE HACE NADA PS ES CONSTANTE NUMERO
             */
        }
        else if(((Lexema)nodo.getElement()).getTipo_lexema() == 3)
        {
            System.out.println("IZQUIERDA DE = : "+((Lexema)nodo.getIzquierda().getElement()).getLexema());
            System.out.println("DERECHA DE = : "+((Lexema)nodo.getDerecha().getElement()).getLexema());

            if(nodo.getDerecha() != null && nodo.getIzquierda() != null)
            {
                String tabla_campo = "";

                if( (((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4
                        && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 5)
                     || (((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 5
                        && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 4)
                        )
                {
                /*
                 * NOTA: ACA SE DEBE VERIFICAR SI EL CAMPO ES UNA CADENA
                 */
                    String nombre_tabla_ident = null;
                    String nombre_campo_ident = null;
                    String const_cad = null;

                    if( ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4 )
                    {
                        tabla_campo = ((Lexema)nodo.getIzquierda().getElement()).getLexema();
                        const_cad = ((Lexema)nodo.getDerecha().getElement()).getLexema().replace("'", "");

                    }
                    else
                    {
                        tabla_campo = ((Lexema)nodo.getDerecha().getElement()).getLexema();
                        const_cad = ((Lexema)nodo.getIzquierda().getElement()).getLexema().replace("'", "");
                    }

                    if( buscarPuntoCadena(tabla_campo) == 0 )
                    {
                        if(buscarCamposEnArbolFrom(nodo_from, tabla_campo) == 1)
                        {
                            String nombre_tabla = buscarTablaDeCampo(nodo_from, tabla_campo);
                            if( !nombre_tabla.equals("") )
                            {
                                String tipo_dato_campo = buscarTipoDatoDeCampo(nodo_from
                                                                    , tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                                    , nombre_tabla);
                                if( tipo_dato_campo.equals("varchar") )
                                {
                                    nombre_tabla_ident = nombre_tabla;
                                    nombre_campo_ident = tabla_campo;
                                }
                                else
                                {
                                    lista_errores_seleccion.add(new Error("CAMPOS WHERE", "LOS TIPOS DE DATOS NO CORRESPONDEN"));
                                }
                            }
                            else
                            {
                                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                            }
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                        }
                    }
                    else if( buscarPuntoCadena(tabla_campo) == 1 )
                    {
                        if(buscarCamposEnArbolFrom(nodo_from, tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                    , tabla_campo.substring(0, tabla_campo.indexOf('.'))) == 1)
                        {
                            String nombre_tabla = tabla_campo.substring(0, tabla_campo.indexOf('.'));
                            if( !nombre_tabla.equals("") )
                            {
                                String tipo_dato_campo = buscarTipoDatoDeCampo(nodo_from
                                                                    , tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                                    , nombre_tabla);
                                if( tipo_dato_campo.equals("varchar") )
                                {
                                    nombre_tabla_ident = nombre_tabla;
                                    nombre_campo_ident = tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length());
                                    /*
                                     * AQUI GENERA LA TABLA PARA ESTE OPERADOR
                                     */
                                }
                                else
                                {
                                    lista_errores_seleccion.add(new Error("CAMPOS WHERE", "LOS TIPOS DE DATOS NO CORRESPONDEN"));
                                }
                            }
                            else
                            {
                                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                            }
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS WHERE", "UN IDENTIFICADOR EN WHERE DEBE TENER A LO MAS UN PUNTO"));
                        }
                    }
                    else
                    {
                        /*
                         * ERROR
                         */
                    }
                    if(nombre_tabla_ident != null && nombre_campo_ident != null && lista_errores_seleccion.isEmpty())
                    {
                        Igual obj_igual = new Igual(tabla_obj_query);
                        nodo.setMatriz_query(obj_igual.generarMatrizIgualIdentConstCad(new ObjetoQuery(nombre_tabla_ident, nombre_campo_ident, null)
                                                                , const_cad));
                    }
                    else
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                    }

                }

                else if( (((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4
                        && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 6)
                     || (((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 6
                        && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 4)
                        )
                {
                /*
                 * NOTA: ACA SE DEBE VERIFICAR SI EL CAMPO ES UN NUMERO
                 */
                    String nombre_tabla_ident = null;
                    String nombre_campo_ident = null;
                    double const_num;

                    if( ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4 )
                    {
                        tabla_campo = ((Lexema)nodo.getIzquierda().getElement()).getLexema();
                        const_num = Double.parseDouble(((Lexema)nodo.getDerecha().getElement()).getLexema());
                    }
                    else
                    {
                        tabla_campo = ((Lexema)nodo.getDerecha().getElement()).getLexema();
                        const_num = Double.parseDouble(((Lexema)nodo.getIzquierda().getElement()).getLexema());
                    }

                    if( buscarPuntoCadena(tabla_campo) == 0 )
                    {
                        if(buscarCamposEnArbolFrom(nodo_from, tabla_campo) == 1)
                        {
                            String nombre_tabla = buscarTablaDeCampo(nodo_from, tabla_campo);
                            if( !nombre_tabla.equals("") )
                            {
                                String tipo_dato_campo = buscarTipoDatoDeCampo(nodo_from
                                                                    , tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                                    , nombre_tabla);
                                if( tipo_dato_campo.equals("double") )
                                {
                                    nombre_tabla_ident = nombre_tabla;
                                    nombre_campo_ident = tabla_campo;
                                }
                                else
                                {
                                    lista_errores_seleccion.add(new Error("CAMPOS WHERE", "LOS TIPOS DE DATOS NO CORRESPONDEN"));
                                }
                            }
                            else
                            {
                                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                            }
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                        }
                    }
                    else if( buscarPuntoCadena(tabla_campo) == 1 )
                    {
                        if(buscarCamposEnArbolFrom(nodo_from, tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                    , tabla_campo.substring(0, tabla_campo.indexOf('.'))) == 1)
                        {
                            String nombre_tabla = tabla_campo.substring(0, tabla_campo.indexOf('.'));
                            if( !nombre_tabla.equals("") )
                            {
                                String tipo_dato_campo = buscarTipoDatoDeCampo(nodo_from
                                                                    , tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                                    , nombre_tabla);
                                if( tipo_dato_campo.equals("double") )
                                {
                                    nombre_tabla_ident = nombre_tabla;
                                    nombre_campo_ident = tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length());
                                    /*
                                     * AQUI GENERA LA TABLA PARA ESTE OPERADOR
                                     */
                                }
                                else
                                {
                                    lista_errores_seleccion.add(new Error("CAMPOS WHERE", "LOS TIPOS DE DATOS NO CORRESPONDEN"));
                                }
                            }
                            else
                            {
                                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                            }
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                        }
                    }
                    else
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "UN IDENTIFICADOR EN WHERE DEBE TENER A LO MAS UN PUNTO"));
                    }
                    if(nombre_tabla_ident != null && nombre_campo_ident != null && lista_errores_seleccion.isEmpty())
                    {
                        Igual obj_igual = new Igual(tabla_obj_query);
                        nodo.setMatriz_query(obj_igual.generarMatrizIgualIdentConstNum(new ObjetoQuery(nombre_tabla_ident, nombre_campo_ident, null)
                                                                , const_num));
                    }
                    else
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                    }

                }
                else if( ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4
                        && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 4 )
                {
                    /*
                     * NOTA: ACA SE DEBE VERIFICAR SI LOS DOS IDENTIFICADORES SON DEL MISMO TIPO DE DATO
                     */
                    String tipo_dato_nodo_izquierdo = "";
                    String tipo_dato_nodo_derecho = "";
                    String nombre_tabla_izq = null;
                    String nombre_tabla_der = null;
                    String nombre_campo_izq = null;
                    String nombre_campo_der = null;

                    tabla_campo = ((Lexema)nodo.getIzquierda().getElement()).getLexema();

                    if( buscarPuntoCadena(tabla_campo) == 0 )
                    {
                        if(buscarCamposEnArbolFrom(nodo_from, tabla_campo) == 1)
                        {
                            String nombre_tabla = buscarTablaDeCampo(nodo_from, tabla_campo);
                            if( !nombre_tabla.equals("") )
                            {
                                tipo_dato_nodo_izquierdo = buscarTipoDatoDeCampo(nodo_from
                                                                    , tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                                    , nombre_tabla);
                                nombre_tabla_izq = nombre_tabla;
                                nombre_campo_izq = tabla_campo;
                            }
                            else
                            {
                                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                            }
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                        }
                    }
                    else if( buscarPuntoCadena(tabla_campo) == 1 )
                    {
                        if(buscarCamposEnArbolFrom(nodo_from, tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                    , tabla_campo.substring(0, tabla_campo.indexOf('.'))) == 1)
                        {
                            String nombre_tabla = tabla_campo.substring(0, tabla_campo.indexOf('.'));
                            if( !nombre_tabla.equals("") )
                            {
                                tipo_dato_nodo_izquierdo = buscarTipoDatoDeCampo(nodo_from
                                                                    , tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                                    , nombre_tabla);
                                nombre_tabla_izq = nombre_tabla;
                                nombre_campo_izq = tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() );
                            }
                            else
                            {
                                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                            }
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                        }
                    }
                    else
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "UN IDENTIFICADOR EN WHERE DEBE TENER A LO MAS UN PUNTO"));
                    }

                    tabla_campo = ((Lexema)nodo.getDerecha().getElement()).getLexema();

                    if( buscarPuntoCadena(tabla_campo) == 0 )
                    {
                        if(buscarCamposEnArbolFrom(nodo_from, tabla_campo) == 1)
                        {
                            String nombre_tabla = buscarTablaDeCampo(nodo_from, tabla_campo);
                            if( !nombre_tabla.equals("") )
                            {
                                tipo_dato_nodo_derecho = buscarTipoDatoDeCampo(nodo_from
                                                                    , tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                                    , nombre_tabla);
                                nombre_tabla_der = nombre_tabla;
                                nombre_campo_der = tabla_campo;
                            }
                            else
                            {
                                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                            }
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                        }
                    }
                    else if( buscarPuntoCadena(tabla_campo) == 1 )
                    {
                        if(buscarCamposEnArbolFrom(nodo_from, tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                    , tabla_campo.substring(0, tabla_campo.indexOf('.'))) == 1)
                        {
                            String nombre_tabla = tabla_campo.substring(0, tabla_campo.indexOf('.'));
                            if( !nombre_tabla.equals("") )
                            {
                                tipo_dato_nodo_derecho = buscarTipoDatoDeCampo(nodo_from
                                                                    , tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() )
                                                                    , nombre_tabla);
                                nombre_tabla_der = nombre_tabla;
                                nombre_campo_der = tabla_campo.substring(tabla_campo.indexOf('.')+1, tabla_campo.length() );
                            }
                            else
                            {
                                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EL NOMBRE DE TABLA NO EXISTE EN FROM"));
                            }
                        }
                        else
                        {
                            lista_errores_seleccion.add(new Error("CAMPOS WHERE", "EXISTE DOS CAMPOS O MAS CAMPOS IGUALES EN LAS TABLAS DEFINIDAS EN FROM O EL CAMPO NO EXISTE EN LAS TABLAS DEFINIDAS EN FROM"));
                        }
                    }
                    else
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "UN IDENTIFICADOR EN WHERE DEBE TENER A LO MAS UN PUNTO"));
                    }

                    if( tipo_dato_nodo_derecho.equals(tipo_dato_nodo_izquierdo) )
                    {
                        /*
                         * EJECUTAR OPERADOR
                         */
                        Igual obj_igual = new Igual(tabla_obj_query);
                        nodo.setMatriz_query(obj_igual.generarMatrizIgualIdentificadores(new ObjetoQuery(nombre_tabla_izq, nombre_campo_izq, null)
                                                                  ,new ObjetoQuery(nombre_tabla_der, nombre_campo_der, null)) );
                    }
                    else
                    {
                        lista_errores_seleccion.add(new Error("CAMPOS WHERE", "LOS TIPOS DE DATOS NO COINCIDEN"));
                    }
                }
                else
                {
                    lista_errores_seleccion.add(new Error("CAMPOS WHERE", "UN OPERADOR DEBE ESTAR RODEADO DE IDENTIFICADORES"));
                }
            }
            else
            {
                lista_errores_seleccion.add(new Error("CAMPOS WHERE", "UN OPERADOR DEBE ESTAR RODEADO DE IDENTIFICADORES"));
            }
        }
        else if(((Lexema)nodo.getElement()).getTipo_lexema() == 1 
                && ( ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("and")
                    || ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("or")) )
        {
            if(lista_errores_seleccion.isEmpty())
            {
                if(nodo.getDerecha() != null && nodo.getIzquierda() != null
                   && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 3
                   && (    ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 3
                        || ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 1) )
                {
                    if(((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("and"))
                    {
                        And obj_and = new And(nodo.getIzquierda().getMatriz_query()
                                                , nodo.getDerecha().getMatriz_query());
                        obj_and.intersectarMatrices();
                        nodo.setMatriz_query(obj_and.intersectarMatrices());
                    }
                    else
                    {
                        Or obj_or = new Or(nodo.getIzquierda().getMatriz_query()
                                                , nodo.getDerecha().getMatriz_query());
                        nodo.setMatriz_query(obj_or.unirMatrices());
                    }
                }
            }
            
        }
        else if( ((Lexema)nodo.getElement()).getTipo_lexema() == 1
                &&  ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("where") )
        {
            tabla_obj_query = nodo.getIzquierda().getMatriz_query();
            /*
             * ERROR
             */
        }
        else
        {
            /*
             * ERROR
             */
        }
    }

    public int buscarPuntoCadena(String cadena)
    {
        int numero_repitencia_punto = 0;
        for(int i = 0; i<cadena.length(); i++)
        {
            if(cadena.charAt(i) == '.')
            {
                numero_repitencia_punto++;
            }
        }
        return numero_repitencia_punto;
    }


    public String buscarTipoDatoDeCampo(BTree nodo, String nombre_campo, String nombre_tabla)
    {
        String tipo_dato_campo = "";

        if( nodo.getIzquierda()!= null )
        {
            tipo_dato_campo = tipo_dato_campo + buscarTipoDatoDeCampo(nodo.getIzquierda(), nombre_campo, nombre_tabla);
        }
        if(nodo.getDerecha() != null)
        {
            tipo_dato_campo = tipo_dato_campo + buscarTipoDatoDeCampo(nodo.getDerecha(), nombre_campo, nombre_tabla);
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4 && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals(nombre_tabla.toLowerCase()) )
        {
            Archivo carchivo = new Archivo();
            carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

            if( !carchivo.getContenido_archivo().isEmpty() )
            {
                XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");
                ArrayList arreglo = xml_.leerXMLArchivosCondicion("campo", "nombre",nombre_campo.toLowerCase());

                if(arreglo.size() == 1)
                {
                    tipo_dato_campo = arreglo.get(0).toString();
                }
            }
            else
            {
                System.out.println("EL ARCHIVO "+((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def NO EXISTE");
            }
        }
        return tipo_dato_campo;
    }

    public String buscarTablaDeCampo(BTree nodo, String nombre_campo)
    {
        String nombre_tabla = "";

        if( nodo.getIzquierda()!= null )
        {
            nombre_tabla = nombre_tabla + buscarTablaDeCampo(nodo.getIzquierda(), nombre_campo);
//            buscarTablaDeCampo(nodo.getIzquierda(), nombre_campo);
        }
        if(nodo.getDerecha() != null)
        {
            nombre_tabla = nombre_tabla + buscarTablaDeCampo(nodo.getDerecha(), nombre_campo);
//            buscarTablaDeCampo(nodo.getIzquierda(), nombre_campo);
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4 )
        {
            Archivo carchivo = new Archivo();
            carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

            if( !carchivo.getContenido_archivo().isEmpty() )
            {
                XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");
                ArrayList arreglo = xml_.leerXMLArchivos("campo", "nombre");

                for (int i = 0; i < arreglo.size(); i++ )
                {
                    if(arreglo.get(i).toString().toLowerCase().equals(nombre_campo.toLowerCase()))
                    {
                        nombre_tabla = ((Lexema)nodo.getElement()).getLexema().toLowerCase();
                    }
                }
            }
            else
            {
                System.out.println("EL ARCHIVO "+((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def NO EXISTE");
            }
        }
        return nombre_tabla;
    }


    public int buscarCamposEnArbolFrom(BTree nodo, String nombre_campo, String nombre_tabla)
    {
        int num_repitencias_campo = 0;

        if( nodo.getIzquierda()!= null )
        {
            num_repitencias_campo = num_repitencias_campo + buscarCamposEnArbolFrom(nodo.getIzquierda(), nombre_campo, nombre_tabla);
        }
        if(nodo.getDerecha() != null)
        {
            num_repitencias_campo = num_repitencias_campo + buscarCamposEnArbolFrom(nodo.getDerecha(), nombre_campo, nombre_tabla);
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4 
                && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals(nombre_tabla.toLowerCase()))
        {
            Archivo carchivo = new Archivo();
            carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

            if( !carchivo.getContenido_archivo().isEmpty() )
            {
                XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");
                ArrayList arreglo = xml_.leerXMLArchivos("campo", "nombre");

                for (int i = 0; i < arreglo.size(); i++ )
                {
                    if(arreglo.get(i).toString().toLowerCase().equals(nombre_campo.toLowerCase()))
                    {
                        num_repitencias_campo = num_repitencias_campo + 1;
                    }
                }
            }
            else
            {
                System.out.println("EL ARCHIVO "+((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def NO EXISTE");
            }
        }
        return num_repitencias_campo;
    }

    public int buscarCamposEnArbolFrom(BTree nodo, String nombre_campo)
    {
        int num_repitencias_campo = 0;

        if( nodo.getIzquierda()!= null )
        {
            num_repitencias_campo = num_repitencias_campo + buscarCamposEnArbolFrom(nodo.getIzquierda(), nombre_campo);
        }
        if(nodo.getDerecha() != null)
        {
            num_repitencias_campo = num_repitencias_campo + buscarCamposEnArbolFrom(nodo.getDerecha(), nombre_campo);
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4 )
        {
            Archivo carchivo = new Archivo();
            carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

            if( !carchivo.getContenido_archivo().isEmpty() )
            {
                XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");
                ArrayList arreglo = xml_.leerXMLArchivos("campo", "nombre");

                for (int i = 0; i < arreglo.size(); i++ )
                {
                    if(arreglo.get(i).toString().toLowerCase().equals(nombre_campo.toLowerCase()))
                    {
                        num_repitencias_campo = num_repitencias_campo + 1;
                    }
                }
            }
            else
            {
                System.out.println("EL ARCHIVO "+((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def NO EXISTE");
            }
        }
        return num_repitencias_campo;
    }

    public void recorrerSubArbolFrom(BTree nodo)
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolFrom(nodo.getIzquierda());
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolFrom(nodo.getDerecha());
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4 )
        {
            Archivo carchivo = new Archivo();
            carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_datos/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_dat.xml");

            if( !carchivo.getContenido_archivo().isEmpty() )
            {

                XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_datos/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_dat.xml");

                productoCartesiano(xml_.leerArchivosDatos(((Lexema)nodo.getElement()).getLexema().toLowerCase()));

            }
            else
            {
                lista_errores_seleccion.add(new Error("BLOQUE FROM", "LA TABLA DEFINIDA EN FROM NO EXISTE"));
                System.out.println("EL ARCHIVO "+((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def NO EXISTE");
            }
        }
        else if ( ((Lexema)nodo.getElement()).getTipo_lexema() == 2
                && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals(",") )
        {
            if( !( (((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4
                    || ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 2 )
                    && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 4) )
            {
                System.out.println("---------------*------*-*--*-*-*-*-*-*-*-*-ENTRA AQUI_1");
                lista_errores_seleccion.add(new Error("BLOQUE FROM", "FALTA UN IDENTIFICADOR DE TABLA"));
            }

        }
        else if( ( ((Lexema)nodo.getElement()).getTipo_lexema() == 1 )
                && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("from") )
        {
            if( !(  (((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 2
                    && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 0)
                   || ((((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4
                    && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 0))) 
                    ) 
            {
                System.out.println("---------------*------*-*--*-*-*-*-*-*-*-*-ENTRA AQUI_2");
                lista_errores_seleccion.add(new Error("BLOQUE FROM", "FALTA UN IDENTIFICADOR DE TABLA"));
            }
        }
//        else
//        {
//            lista_errores_seleccion.add(new Error("BLOQUE SELECCION", "LA SENTENCIA FROM ESTA MAL DEFINIDA"));
//        }
    }

    /*
     * ESTE METODO REALIZA EL PRODUCTO CARTESIANO DE LAS TABLAS DEL SUBARBOL FROM
     */
    public void productoCartesiano(ObjetoQuery[][] tabla)
    {
        ObjetoQuery tabla_aux[][] = new ObjetoQuery[0][0];
        int num_filas = 0;
        int num_columnas = 0;

        if(tabla_obj_query.length == 0)
        {
            tabla_obj_query = tabla;
        }
        else
        {
            tabla_aux = tabla_obj_query;
            num_filas = tabla_aux.length * tabla.length;
            num_columnas = tabla_aux[0].length + tabla[0].length;

            tabla_obj_query = new ObjetoQuery[num_filas][num_columnas];

            int contador = 0;

            for(int i = 0; i<tabla_aux.length; i++)
            {
                for(int j = (i*tabla.length); j< (i+1)*tabla.length; j++)
                {
                    for(int m = 0; m <tabla_aux[0].length; m++)
                    {
                        tabla_obj_query[j][m] = tabla_aux[i][m];
                    }
                    for(int n = tabla_aux[0].length; n < tabla[0].length+tabla_aux[0].length; n++)
                    {
                        tabla_obj_query[j][n] = tabla[contador][n-tabla_aux[0].length];
                    }
                   contador++;
                }
                contador = 0;
            }

            for(int i = 0; i<tabla_obj_query.length; i++)
            {
                for(int j = 0; j< tabla_obj_query[0].length; j++)
                {
                    System.out.print(tabla_obj_query[i][j].getObjeto().toString()+" | ");
                }
                System.out.println("");
            }

        }
    }


    /**
     * @return the lista_lexemas
     */
    public ArrayList getLista_lexemas() {
        return lista_lexemas;
    }

    /**
     * @param lista_lexemas the lista_lexemas to set
     */
    public void setLista_lexemas(ArrayList lista_lexemas) {
        this.lista_lexemas = lista_lexemas;
    }

}
